function _slicedToArray(arr, i) {
  return (
    _arrayWithHoles(arr) ||
    _iterableToArrayLimit(arr, i) ||
    _unsupportedIterableToArray(arr, i) ||
    _nonIterableRest()
  );
}
function _nonIterableRest() {
  throw new TypeError(
    'Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.',
  );
}
function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === 'string') return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === 'Object' && o.constructor) n = o.constructor.name;
  if (n === 'Map' || n === 'Set') return Array.from(o);
  if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
    return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;
  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  return arr2;
}
function _iterableToArrayLimit(arr, i) {
  var _i =
    null == arr
      ? null
      : ('undefined' != typeof Symbol && arr[Symbol.iterator]) || arr['@@iterator'];
  if (null != _i) {
    var _s,
      _e,
      _x,
      _r,
      _arr = [],
      _n = !0,
      _d = !1;
    try {
      if (((_x = (_i = _i.call(arr)).next), 0 === i)) {
        if (Object(_i) !== _i) return;
        _n = !1;
      } else
        for (
          ;
          !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i);
          _n = !0
        );
    } catch (err) {
      (_d = !0), (_e = err);
    } finally {
      try {
        if (!_n && null != _i.return && ((_r = _i.return()), Object(_r) !== _r)) return;
      } finally {
        if (_d) throw _e;
      }
    }
    return _arr;
  }
}
function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}
import { MenuUnfoldOutlined, ReloadOutlined } from '@ant-design/icons';
import { message } from 'antd';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { IMAGE_STATUS } from './enums';
import './index.less';
import { createClipPath } from './utils';

/**
 * 图片滑动验证
 */
export default function ImageSliderVerify(_ref) {
  var imageUrl = _ref.imageUrl,
    _ref$shadowSize = _ref.shadowSize,
    shadowSize = _ref$shadowSize === void 0 ? 50 : _ref$shadowSize,
    _ref$imageWidth = _ref.imageWidth,
    imageWidth = _ref$imageWidth === void 0 ? 300 : _ref$imageWidth,
    _ref$imageHeight = _ref.imageHeight,
    imageHeight = _ref$imageHeight === void 0 ? 300 : _ref$imageHeight,
    onSuccess = _ref.onSuccess,
    onFail = _ref.onFail,
    onReload = _ref.onReload;
  var shadowCanvasRef = useRef(null);
  var fragmentCanvasRef = useRef(null);
  var imageStatusRef = useRef(IMAGE_STATUS.LOADING);
  /** 上一次移动记录 */
  var prevMovingRef = useRef({
    x: 0,
  });
  /** 当前移动记录：undefined 表示并未在移动，有值表示在移动 */
  var currMovingRef = useRef();
  var _useState = useState({
      offsetX: 0,
      offsetY: 0,
    }),
    _useState2 = _slicedToArray(_useState, 2),
    offset = _useState2[0],
    setOffset = _useState2[1];
  var _useState3 = useState(0),
    _useState4 = _slicedToArray(_useState3, 2),
    currX = _useState4[0],
    setCurrX = _useState4[1];

  /** 重置 */
  var reset = useCallback(function () {
    imageStatusRef.current = IMAGE_STATUS.LOADING;
    prevMovingRef.current = {
      x: 0,
    };
    currMovingRef.current = undefined;
    setOffset({
      offsetX: 0,
      offsetY: 0,
    });
    setCurrX(0);
  }, []);
  var renderImage = useCallback(
    function () {
      reset();

      // 创建一个图片对象，主要用于canvas.context.drawImage()
      var image = new Image();
      image.addEventListener('load', function () {
        var _shadowCanvasRef$curr, _fragmentCanvasRef$cu;
        var shadowCanvasCtx =
          (_shadowCanvasRef$curr = shadowCanvasRef.current) === null ||
          _shadowCanvasRef$curr === void 0
            ? void 0
            : _shadowCanvasRef$curr.getContext('2d');
        var fragmentCanvasCtx =
          (_fragmentCanvasRef$cu = fragmentCanvasRef.current) === null ||
          _fragmentCanvasRef$cu === void 0
            ? void 0
            : _fragmentCanvasRef$cu.getContext('2d');
        if (!shadowCanvasCtx || !fragmentCanvasCtx) return;
        shadowCanvasCtx.clearRect(0, 0, shadowSize, shadowSize);
        fragmentCanvasCtx.clearRect(0, 0, shadowSize, shadowSize);

        // 让两个ctx拥有同样的裁剪路径(可滑动小块的轮廓)
        var styleIndex = Math.floor(Math.random() * 16);
        createClipPath(shadowCanvasCtx, shadowSize, styleIndex);
        createClipPath(fragmentCanvasCtx, shadowSize, styleIndex);
        var shadowPosition = {
          x: Math.floor(shadowSize + (imageWidth - 2 * shadowSize) * Math.random()),
          y: Math.floor((imageHeight - shadowSize) * Math.random()),
        };

        // 让小块绘制出被裁剪的部分
        fragmentCanvasCtx.drawImage(
          image,
          shadowPosition.x,
          shadowPosition.y,
          shadowSize,
          shadowSize,
          0,
          0,
          shadowSize,
          shadowSize,
        );

        // 让阴影 canvas 带上阴影效果
        shadowCanvasCtx.fillStyle = 'rgba(0, 0, 0, 0.8)';
        shadowCanvasCtx.fill();

        // 恢复画布状态
        shadowCanvasCtx.restore();
        fragmentCanvasCtx.restore();

        // 设置裁剪小块的位置
        setOffset({
          offsetX: shadowPosition.x,
          offsetY: shadowPosition.y,
        });
        imageStatusRef.current = IMAGE_STATUS.READY;
      });
      image.src = imageUrl;
    },
    [reset],
  );
  useEffect(
    function () {
      renderImage();
    },
    [imageUrl],
  );

  /** 重刷 */
  var reload = useCallback(
    function () {
      var _shadowCanvasRef$curr2, _fragmentCanvasRef$cu2;
      if (
        imageStatusRef.current !== IMAGE_STATUS.READY &&
        imageStatusRef.current !== IMAGE_STATUS.MATCH
      )
        return;
      var shadowCanvasCtx =
        (_shadowCanvasRef$curr2 = shadowCanvasRef.current) === null ||
        _shadowCanvasRef$curr2 === void 0
          ? void 0
          : _shadowCanvasRef$curr2.getContext('2d');
      var fragmentCanvasCtx =
        (_fragmentCanvasRef$cu2 = fragmentCanvasRef.current) === null ||
        _fragmentCanvasRef$cu2 === void 0
          ? void 0
          : _fragmentCanvasRef$cu2.getContext('2d');
      if (!shadowCanvasCtx || !fragmentCanvasCtx) return;
      shadowCanvasCtx.clearRect(0, 0, shadowSize, shadowSize);
      fragmentCanvasCtx.clearRect(0, 0, shadowSize, shadowSize);
      reset();
      onReload();
    },
    [onReload, reset, renderImage],
  );

  /** 移动开始 */
  var handleMoveStart = useCallback(function (x) {
    if (imageStatusRef.current !== IMAGE_STATUS.READY) return;
    currMovingRef.current = {
      x: x,
    };
  }, []);
  var handleMouseDown = useCallback(
    function (e) {
      handleMoveStart(e.clientX);
    },
    [handleMoveStart],
  );
  var handleTouchStart = useCallback(
    function (e) {
      handleMoveStart(e.touches[0].pageX);
    },
    [handleMoveStart],
  );
  var handleMove = useCallback(function (x) {
    var _prevMovingRef$curren;
    if (imageStatusRef.current !== IMAGE_STATUS.READY || !currMovingRef.current) return;
    var distance = x - currMovingRef.current.x;
    var currX =
      ((_prevMovingRef$curren = prevMovingRef.current) === null || _prevMovingRef$curren === void 0
        ? void 0
        : _prevMovingRef$curren.x) + distance;
    var minX = 0;
    var maxX = imageWidth - shadowSize;
    currX = currX < minX ? 0 : currX > maxX ? maxX : currX;
    requestAnimationFrame(function () {
      setCurrX(currX);
    });
  }, []);
  var handleMouseMove = useCallback(
    function (e) {
      handleMove(e.clientX);
    },
    [handleMove],
  );
  var handleTouchMove = useCallback(
    function (e) {
      handleMove(e.touches[0].pageX);
    },
    [handleMove],
  );
  var handleMoveEnd = useCallback(
    function () {
      var _offset$offsetX;
      if (imageStatusRef.current !== IMAGE_STATUS.READY || !currMovingRef.current) return;
      currMovingRef.current = undefined;
      prevMovingRef.current = {
        x: currX,
      };
      var isMatch =
        Math.abs(
          currX -
            ((_offset$offsetX = offset.offsetX) !== null && _offset$offsetX !== void 0
              ? _offset$offsetX
              : 0),
        ) < 5;
      if (isMatch) {
        var _offset$offsetX2;
        imageStatusRef.current = IMAGE_STATUS.MATCH;
        setCurrX(
          (_offset$offsetX2 = offset.offsetX) !== null && _offset$offsetX2 !== void 0
            ? _offset$offsetX2
            : 0,
        );
        message.success('验证成功');
        onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
      } else {
        var timer = setTimeout(function () {
          prevMovingRef.current = {
            x: 0,
          };
          setCurrX(0);
          clearTimeout(timer);
        }, 1000);
        message.error('验证失败');
        onFail === null || onFail === void 0 ? void 0 : onFail();
      }
    },
    [currX, offset, onSuccess, onFail],
  );
  return /*#__PURE__*/ React.createElement(
    'div',
    {
      className: 'szzj-image-slider-verify',
      style: {
        width: imageWidth,
      },
    },
    /*#__PURE__*/ React.createElement(
      'div',
      {
        className: 'image-container',
        style: {
          height: imageHeight,
          backgroundImage: 'url("'.concat(imageUrl, '")'),
        },
      },
      /*#__PURE__*/ React.createElement('canvas', {
        ref: shadowCanvasRef,
        className: 'canvas',
        width: shadowSize,
        height: shadowSize,
        style: {
          left: offset.offsetX,
          top: offset.offsetY,
        },
      }),
      /*#__PURE__*/ React.createElement('canvas', {
        ref: fragmentCanvasRef,
        className: 'canvas',
        width: shadowSize,
        height: shadowSize,
        style: {
          top: offset.offsetY,
          left: currX,
        },
      }),
    ),
    /*#__PURE__*/ React.createElement(
      'div',
      {
        className: 'reload-container',
        onClick: reload,
      },
      /*#__PURE__*/ React.createElement(ReloadOutlined, {
        className: 'reload-icon',
      }),
      /*#__PURE__*/ React.createElement(
        'span',
        {
          className: 'reload-tips',
        },
        '\u5237\u65B0\u9A8C\u8BC1',
      ),
    ),
    /*#__PURE__*/ React.createElement(
      'div',
      {
        className: 'slider-container',
        onMouseLeave: handleMoveEnd,
      },
      /*#__PURE__*/ React.createElement(
        'div',
        {
          className: 'slider-bar',
        },
        '\u62D6\u52A8\u6ED1\u5757\u5B8C\u6210\u62FC\u56FE',
      ),
      /*#__PURE__*/ React.createElement(
        'div',
        {
          className: 'slider-button',
          onTouchStart: handleTouchStart,
          onTouchMove: handleTouchMove,
          onTouchEnd: handleMoveEnd,
          onMouseDown: handleMouseDown,
          onMouseMove: handleMouseMove,
          onMouseUp: handleMoveEnd,
          style: {
            left: currX + 'px',
          },
        },
        /*#__PURE__*/ React.createElement(MenuUnfoldOutlined, {
          style: {
            textAlign: 'center',
            lineHeight: '44px',
            width: '44px',
          },
        }),
      ),
    ),
  );
}
